package mammuthus.web.action;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.webdm.common.tools.NumberUtil;
import mammuthus.client.ConfClient;
import mammuthus.web.service.ConfClientService;
import mammuthus.web.service.SlaveService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import scala.Tuple3;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by fengbingjian on 15/3/26 09:43.
 */
@Controller()
@RequestMapping("appManager")
public class AppManagerAction {

    private ConfClient confClient;
    private Logger logger = Logger.getLogger(AppManagerAction.class);


    @Autowired
    private SlaveService slaveService;

    @Autowired
    public void setConfClientService(ConfClientService confClientService) {

        confClient = confClientService.getConfClient();

    }

    @RequestMapping("appIndex.html")
    public String index(HttpServletRequest req){


        List<String> apps = confClient.zKClientWrapper().listConf(confClient.getPath("/_status/application"));

//        apps.add(0, "all");

        req.setAttribute("apps", apps);

        req.setAttribute("page", "appManager");
        return "appIndex";

    }

    @RequestMapping("appShellIndex.html")
    public String appShellIndex(HttpServletRequest req,
                                @RequestParam(value = "appName", defaultValue = "") String appName,
                                @RequestParam(value = "action", defaultValue = "") String action,
                                @RequestParam(value = "host", defaultValue = "") String host,
                                @RequestParam(value = "param", defaultValue = "") String param){



        List<String> apps = new ArrayList<String>();
        apps.addAll(slaveService.appListSimple());//confClient.zKClientWrapper().listConf(confClient.getPath("/_status/application"));

        apps.add(0, "all");

        req.setAttribute("apps", apps);

        req.setAttribute("appName", appName);
        req.setAttribute("action", action);
        req.setAttribute("host", host);
        req.setAttribute("param", param);


        req.setAttribute("page", "appManager");
        return "appManagerShellIndex";
    }

    @RequestMapping("appLog.html")
    public String appLog(HttpServletRequest req,
                                @RequestParam(value = "appName", defaultValue = "") String appName){



        List<String> apps = confClient.zKClientWrapper().listConf(confClient.getPath("/_status/application"));

        //apps.add(0, "all");

        req.setAttribute("apps", apps);
        req.setAttribute("appName", appName);

        req.setAttribute("page", "appShellIndex");
        req.setAttribute("log", true);
        return "appShellIndex";
    }


    @RequestMapping("appShell.html")
    public String appShell(HttpServletRequest req,
                      @RequestParam(value = "appName", defaultValue = "") String appName,
                      @RequestParam(value = "slave", defaultValue = "") String slave,
                      @RequestParam(value = "action", defaultValue = "") String action,
                      @RequestParam(value = "param", defaultValue = "") String param){




        req.setAttribute("result", shell(appName, slave, action, param));
        req.setAttribute("page", "appManager");

        return "json";
    }

    @RequestMapping("appSlave.html")
    public String getList(HttpServletRequest req,
                          @RequestParam(value = "appName", defaultValue = "all") String appName){

        //String path = "/_status/application/" + appName;
//        if("all".equals(appName)){
//            path = "/_proxy";
//        }
        List<String> slaveList = slaveService.appSlave(appName); //confClient.zKClientWrapper().listConf(confClient.getPath(path));

        if(slaveList == null){

            slaveList = new ArrayList<String>();
        }
        req.setAttribute("result", JSONObject.toJSONString(slaveList));
        req.setAttribute("page", "appManager");

        return "json";
    }

    //http://127.0.0.1:9003/shell?slaves=fbj&shellCommand=ls
    public String shell(String appName, String slave, String action, String param){

//        List<String> slaveList = confClient.zKClientWrapper().listConf(confClient.getPath("/_status/application/" + appName));
//
//        if(slaveList.size() > 0){

           // String slave = StringUtil.ArrtoString(slaveList.toArray(), false);

        if(param != null && !param.isEmpty()){
            param = param.replace(" ", "%20");
        }

            logger.info("appName " + appName + ", slave " + slave + ", action " + action + ", param " + param);

        String result = null;
        if("log".equals(action)){
            result =         slaveService.logDetail(appName, "logs/" + appName + ".log",slave,-1,0)._2();

            Map<String, Object> r = new HashMap<String, Object>();
            r.put("message", result);
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            list.add(r);
            return JSONObject.toJSONString(list);
        }else{
            return  slaveService.getMethodShell(appName,slave, action, param);

        }

//            Map<String, Object> params = new HashMap<String, Object>();
//            params.put("slaves", slave);
//            if("shell".equals(action))
//                //params.put("shellCommand", "[ -d /data/web/applications/" + appName+" ] && cd /data/web/applications/" + appName + "/\n" + param);
//                params.put("shellCommand",  param);
//
//            else
//                params.put("shellCommand", ShellUtil.getShell(appName, action, param));
//                logger.info("shell \n" + params.get("shellCommand"));
//
//            try {
//                return slaveService.shell(slave, params);
//                //return CatchUtil.post("http://appMaster.csdn.net:9003/shell", params);
//            } catch (Exception e) {
//                e.printStackTrace();
//                Map<String, Object> err = new HashMap<String, Object>();
//                err.put("content", e.toString());
//                return JSONObject.toJSONString(err);
//            }


//        }


    }


    @RequestMapping("appManagerLogList.html")
    public String appManagerLogList(HttpServletRequest req,
                          @RequestParam(value = "appName", defaultValue = "") String appName,
                          @RequestParam(value = "path", defaultValue = "/") String path,
                          @RequestParam(value = "host", defaultValue = "") String host
                          ) {



        req.setAttribute("appName", appName);
        req.setAttribute("parent", path);
        req.setAttribute("host", host);
        String arr[] = path.split("/");
        List<String[]> list =  new ArrayList<String[]>();

        StringBuilder tmp = new StringBuilder("/");
        for(String cur: arr){

            if(cur != null && !cur.isEmpty()){

                tmp.append(cur).append("/");
                list.add(new String[]{cur, tmp.toString()});
            }
        }
        req.setAttribute("pathDetail",list);
        req.setAttribute("files",slaveService.listDir(appName,path, host));



        return "appManagerLogList";
    }

    @RequestMapping("appManagerLogDetail.html")
    public String appManagerLogDetail(HttpServletRequest req,
                                    @RequestParam(value = "appName", defaultValue = "") String appName,
                                    @RequestParam(value = "path", defaultValue = "/") String path,
                                    @RequestParam(value = "offset", defaultValue = "0") long offset,
                                    @RequestParam(value = "size", defaultValue = "100000") int size,
                                    @RequestParam(value = "host", defaultValue = "") String host,
                                    @RequestParam(value = "type", defaultValue = "") String type,
                                    @RequestParam(value = "filter", defaultValue = "-") String filter
    ) {



        if(offset < -1l) offset = -1l;
        req.setAttribute("appName", appName);
        req.setAttribute("path", path);
        req.setAttribute("host", host);
        req.setAttribute("size", size);
        req.setAttribute("filter", filter);

        Tuple3<Object, String, Object> tuple2 = slaveService.logDetail(appName,path,host,offset,size);

        long fileMax = 100000;
        req.setAttribute("file", tuple2._2());
        long fileOffset = NumberUtil.getLongValue(tuple2._1());
        long fileLen = NumberUtil.getLongValue(tuple2._3());
        long preOffset = 0;
        if(fileLen <= fileMax){
            preOffset = 0;
            offset = 0;
        }else if(fileLen == fileOffset){
            offset = -1;
            preOffset = fileLen - fileMax * 2;
            if(preOffset < 0) preOffset = 0;
        }else if(fileLen == offset){

            offset = -1;
            preOffset = fileLen - fileMax * 2;
            if(preOffset < 0) preOffset = 0;
        }else{
            offset = fileOffset;
            preOffset =  offset - fileMax * 2;
            if(preOffset < 0)
                preOffset = 0;

        }


        req.setAttribute("preOffset",  preOffset);
        req.setAttribute("offset", offset);

        String arr[] = path.split("/");
        List<String[]> list =  new ArrayList<String[]>();

        StringBuilder tmp = new StringBuilder("/");
        for(String cur: arr){

            if(cur != null && !cur.isEmpty()){

                tmp.append(cur).append("/");
                list.add(new String[]{cur, tmp.toString()});
            }
        }
        req.setAttribute("pathDetail",list);

        if("json".equals(type)){

            JSONObject json = new JSONObject();
            json.put("finished", true);
            json.put("offset", fileOffset);
            json.put("message", tuple2._2());
            JSONArray jsonArray = new JSONArray();
            jsonArray.add(json);
            req.setAttribute("result", jsonArray.toJSONString());
            return "json";
        }else{
            return "appManagerLogDetail";
        }

    }


}
